/**
  ******************************************************************************
  * @author     Chris
  * @since      2024/6/12 10:55
  *
  * @file       pd_gpio.h
  * @brief      Head file of GPIO peripheral driver.
  *
  * @note       This file contains the peripheral driver's function declaration
  *             for the GPIO.
  *
  * @warning    None.
  ******************************************************************************
  * Change Logs:
  *   Date           Author       Notes
  *   2024-06-12     Chris        the first version
  *
  ******************************************************************************
  */

#ifndef JLC_SKY_GPIO_H
#define JLC_SKY_GPIO_H

#include "stm32f407xx.h"


struct GPIOVtbl;

// Object properties
typedef struct {
    GPIO_TypeDef *GPIOx;
    uint32_t Pin;
    uint32_t Mode;
    uint32_t Speed;
    uint32_t OutputType;
    uint32_t Pull;
    uint32_t Alternate;

    struct GPIOVtbl *vptr;
} GPIO;

// Object virtual table
struct GPIOVtbl {
    void (*init)(const GPIO *this);

    uint8_t (*get)(const GPIO *this);

    void (*set)(const GPIO *this);

    void (*reset)(const GPIO *this);

    void (*set_out_mode)(const GPIO *this);

    void (*set_in_mode)(const GPIO *this);
};

// Object constructor and member function
void GPIO_constructor(GPIO *this, GPIO_TypeDef *GPIOx, const uint32_t Pin);

static inline void GPIO_init(const GPIO *this) {
    this->vptr->init(this);
}

static inline uint8_t GPIO_get(const GPIO *this) {
    return this->vptr->get(this);
}

static inline void GPIO_set(const GPIO *this) {
    this->vptr->set(this);
}

static inline void GPIO_reset(const GPIO *this) {
    this->vptr->reset(this);
}

static inline void GPIO_setOutMode(const GPIO *this) {
    this->vptr->set_out_mode(this);
}

static inline void GPIO_setInMode(const GPIO *this) {
    this->vptr->set_in_mode(this);
}


struct GPIOListVtbl;

// Object properties
typedef struct {
    struct GPIOListVtbl *vptr;

    GPIO *gpios;
    uint8_t gpioSize;
} GPIOList;

// Object virtual table
struct GPIOListVtbl {
    void (*init)(const GPIOList *this);
};

// Object constructor and member function
void GPIOList_constructor(GPIOList *this, GPIO *gpios, uint8_t gpioSize);


#endif //JLC_SKY_GPIO_H
